package com.example.recycler.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Path
import android.util.AttributeSet
import android.util.Half.toFloat
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.RelativeLayout
import android.widget.TextView
import com.example.recycler.R
import com.example.recycler.bean.CircleBean
import com.example.recycler.bean.StarryBean
import com.example.recycler.ext.dp2px
import me.jessyan.autosize.utils.AutoSizeUtils

/**
 * Created by 舍长 on 2019/5/16
 * describe:自定义复杂交错的列表
 */
class StarryListView(context: Context, attrs: AttributeSet?) : FrameLayout(context, attrs) {

    //进度实体列表
    private var mList = ArrayList<StarryBean>()

    //item位置，圆点坐标实体类列表
    private var mDistanceList = ArrayList<CircleBean>()

    //背景path路径，透明度30%，颜色为白色
    private var mBackPath = Path()

    //已经完成进度的path路径，透明度100%，白色
    private var mCurrentPath = Path()

    //背景画笔
    private var mBackPaint = Paint()

    //已经完成进度的画笔
    private var mCurrentPaint = Paint()

    //区间组件的间隔
    public var mInterval=424f

    init {
        //初始化4个基准点的距离,具体坐标看蓝湖的设计图,
        //注意圆点距离左边标注图给出的是86，但是还要加上圆点的半径，就是87
        //这里在一开始就将单位数值为dp的数值转换成px，后面就直接用就可以了
        mDistanceList.add(CircleBean(dp2px(22f), dp2px(0f), dp2px(91f), dp2px(69f)))
        mDistanceList.add(CircleBean(dp2px(118f), dp2px(31f), dp2px(245f), dp2px(158f)))
        mDistanceList.add(CircleBean(dp2px(38f), dp2px(209f), dp2px(107f), dp2px(278f)))
        mDistanceList.add(CircleBean(dp2px(118f), dp2px(307f), dp2px(187f), dp2px(376f)))

        //初始化背景路径画笔
        mBackPaint.style = Paint.Style.STROKE
        mBackPaint.strokeWidth = AutoSizeUtils.dp2px(context, 1f).toFloat()//画笔大小
        mBackPaint.color = resources.getColor(R.color.color30FFFFFF)//画笔颜色

        //初始化实际路径画笔
        mCurrentPaint.style = Paint.Style.STROKE
        mCurrentPaint.strokeWidth = AutoSizeUtils.dp2px(context, 1f).toFloat()//画笔大小
        mCurrentPaint.color = resources.getColor(R.color.public_colorWhite)//画笔颜色

        //在ViewGroup容器级自定义控件总，一定要加上这个属性，不然path无法绘制
        setWillNotDraw(false)
    }

    /**
     * 设置相应的数据
     */
    fun setListData(list: ArrayList<StarryBean>) {
        this.mList = list
        //路径的起点就是第一个圆点的坐标
        mBackPath.moveTo(mDistanceList[0].dotX.toFloat(), mDistanceList[0].doty.toFloat()) //未解锁章节路径
        mCurrentPath.moveTo(mDistanceList[0].dotX.toFloat(), mDistanceList[0].doty.toFloat())//已解锁章节路径

        /**
         * 遍历列表
         * 每4个item为一个我们规划好的基础区间，在这个区间上4个item的基础位置是固定的，而到了第二个区间
         * 例如4~8 ，9~12，就是分别在对应的区间加上424dp，即时第5个小圆圈顶部距离第一个小圆圈顶部的距离
         * 计算区间[1,2(大圆圈)，3,4]，计算当前区间倍数的个数是当前所以/4（从第二个区间开始计算），例如5/4=1，就是1倍，第二个区间
         * 所有基础位置数值要加上1*424dp
         * 而判断是具体1,2,3,4哪个基础位置的计算公式为：i - 4 * multiple，
         * 例如，第二个大圆圈，例如，5（数列从0开始）-4*1=1「数列从0开始」
         */
        for (i in 0 until list.size) {
            var multiple = 0//区间倍数
            //当数列索引大于3，也就是第二个区间开始时才开始计算倍数
            if (i > 3) {
                multiple = i / 4
            }
            //绘制背景线段
            mBackPath.lineTo(mDistanceList[i - 4 * multiple].dotX.toFloat(), mDistanceList[i - 4 * multiple].doty.toFloat() + dp2px( mInterval) * multiple)
            //如果已经解锁
            if(list[i].islock){
                mCurrentPath.lineTo(mDistanceList[i - 4 * multiple].dotX.toFloat(), mDistanceList[i - 4 * multiple].doty.toFloat() + dp2px( mInterval) * multiple)
            }
            //设置布局参数
            val params =
                LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
            //计算item需要距离顶部多少距离，基准距离+倍数乘446
            params.topMargin =
                mDistanceList[i - 4 * multiple].marginTop + (dp2px(mInterval) * multiple)
            //如果当前需要添加的item是大圆圈
            if (i == 1 + 4 * multiple) {
                val bigView = LayoutInflater.from(context).inflate(R.layout.item_circle_big, null, false)
                //设置距离左边的距离
                params.leftMargin = mDistanceList[i - 4 * multiple].marginleft
                //初始化控件
                val rlContainer = bigView.findViewById<RelativeLayout>(R.id.rlContainer)//整个布局
                val textView = bigView.findViewById<TextView>(R.id.tvChapterName)//章节名称
                //设置点击事件，当点击item时会回调数列的索引
                rlContainer.setOnClickListener {
                    onClickListener.onSelect(i)
                }
                //设置章节标题
                textView.text = list[i].chapterName
                //将设置好的item View Add到ViewGroup上
                addView(bigView, params)
            } else {
                //如果当前需要添加的item是小圆圈
                val smallView = LayoutInflater.from(context).inflate(R.layout.item_circle_small, null, false)
                //设置距离左边的距离
                params.leftMargin = mDistanceList[i - 4 * multiple].marginleft
                //初始化控件
                val rlContainer = smallView.findViewById<RelativeLayout>(R.id.rlContainer)//整个布局
                val textView = smallView.findViewById<TextView>(R.id.tvChapterName)//章节名称
                //设置点击事件，当点击item时会回调数列的索引
                rlContainer.setOnClickListener {
                    onClickListener.onSelect(i)
                }
                //设置章节标题
                textView.text = list[i].chapterName
                //将设置好的item View Add到ViewGroup上
                addView(smallView, params)
            }

        }
        invalidate()
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        canvas?.drawPath(mBackPath, mBackPaint)//绘制为解锁章节背景虚线
        canvas?.drawPath(mCurrentPath, mCurrentPaint)//绘制已经解锁章节路径
    }

    /**
     * 用来对选中item位置的回调，onSelect方法也可以根据需要设置成实体类，
     * 我是返回集合索引，在Activity中进行处理
     */
    private lateinit var onClickListener: OnClickListener

    interface OnClickListener {
        fun onSelect(index: Int)
    }

    fun setStarryOnClickListener(onProgressListener: OnClickListener) {
        this.onClickListener = onProgressListener
    }
}